package com.sumainfor.zuul.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.sumainfor.common.util.Constant;
import com.sumainfor.common.util.CustomMap;
import com.sumainfor.common.util.JsonResult;
import com.sumainfor.common.util.RRException;
import com.sumainfor.zuul.dao.SysDeptDao;
import com.sumainfor.zuul.entity.DeptMenu;
import com.sumainfor.zuul.entity.SysAreaDeptEntity;
import com.sumainfor.zuul.entity.SysDeptEntity;
import com.sumainfor.zuul.entity.SysRoleDeptEntity;
import com.sumainfor.zuul.service.SysAreaDeptService;
import com.sumainfor.zuul.service.SysDeptService;
import com.sumainfor.zuul.service.SysRoleDeptService;
import com.sumainfor.zuul.util.PageUtils;
import com.sumainfor.zuul.util.Query;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


@Service("sysDeptService")
@Transactional(rollbackFor = Exception.class)
public class SysDeptServiceImpl extends ServiceImpl<SysDeptDao, SysDeptEntity>
        implements SysDeptService {
    Logger log = LoggerFactory.getLogger(SysDeptServiceImpl.class);

    @Autowired
    private SysDeptDao sysDeptDao;

    @Autowired
    private SysAreaDeptService areaDeptService;

    @Autowired
    private SysRoleDeptService roleDeptService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Page<SysDeptEntity> page = this.selectPage(new Query<SysDeptEntity>(
                params).getPage(), new EntityWrapper<SysDeptEntity>());

        return new PageUtils(page);
    }

    @Override
    public List<SysDeptEntity> queryList(Map<String, Object> params) {
        List<SysDeptEntity> deptList = this
                .selectList(new EntityWrapper<SysDeptEntity>().addFilterIfNeed(
                        params.get(Constant.SQL_FILTER) != null,
                        (String) params.get(Constant.SQL_FILTER)));

        for (SysDeptEntity sysDeptEntity : deptList) {
            SysDeptEntity parentDeptEntity = this.selectById(sysDeptEntity
                    .getParentId());
            if (parentDeptEntity != null) {
                sysDeptEntity.setParentName(parentDeptEntity.getName());
            }
        }
        return deptList;
    }

    @Override
    public List<Integer> queryDetpIdList(Integer parentId) {
        return baseMapper.queryDetpIdList(parentId);
    }

    @Override
    public List<Integer> getSubDeptIdList(Integer deptId) {
        // 部门及子部门ID列表
        List<Integer> deptIdList = new ArrayList<>();

        // 获取子部门ID
        List<Integer> subIdList = queryDetpIdList(deptId);
        getDeptTreeList(subIdList, deptIdList);

        return deptIdList;
    }

    /**
     * 递归
     */
    private void getDeptTreeList(List<Integer> subIdList, List<Integer> deptIdList) {
        for (Integer deptId : subIdList) {
            List<Integer> list = queryDetpIdList(deptId);
            if (list.size() > 0) {
                getDeptTreeList(list, deptIdList);
            }

            deptIdList.add(deptId);
        }
    }

    /**
     * 获取所有的部门及上级部门
     *
     * @Description: TODO(这里用一句话描述这个方法的作用)
     * @author zhlu
     * @date 2018年9月20日
     */
    @Override
    public List<Map<String, Object>> getDetpList(Map<String, Object> params) {
        return sysDeptDao.getDetpList(params);
    }

    /**
     * 获取所有的部门及上级部门总数
     *
     * @author zhlu
     * @date 2018年9月20日
     */
    public int getDetpListCount(Map<String, Object> params) {
        return sysDeptDao.getDetpListCount(params);
    }

    @Override
    public List<DeptMenu> findTree(Boolean isShowTop, String areaId) {
        try {// 查询所有菜单

            List<DeptMenu> allMenu;
            if (StringUtils.isNotBlank(areaId)) {
                //查询 根据归属区域
                allMenu = baseMapper.getDeptByAreaId(areaId);
            } else {
                allMenu = sysDeptDao.getParentDetpList();
            }


            DeptMenu root = new DeptMenu();
            root.setPid(-1);
            root.setId(0);
            root.setLabel("最高级别节点");

            // 根节点
            List<DeptMenu> rootMenu = new ArrayList<>();

            if (BooleanUtils.isTrue(isShowTop)) {
                rootMenu.add(root);
            } else {
                for (DeptMenu menu : allMenu) {
                    if (menu.getPid() == 0) {
                        rootMenu.add(menu);
                    }
                }
            }


            for (DeptMenu nav : rootMenu) {
                List<DeptMenu> childList = getChild(nav.getId(), allMenu);
                // 给根节点设置子节点
                nav.setChildren(childList);
            }
            return rootMenu;
        } catch (Exception e) {
            log.error("获取部门菜单失败", e);
            return new ArrayList();
        }
    }

    /**
     * 获取子节点
     *
     * @param id      父节点id
     * @param allMenu 所有菜单列表
     * @return 每个根节点下，所有子菜单列表
     */
    public List<DeptMenu> getChild(Integer id, List<DeptMenu> allMenu) {
        //子菜单
        List<DeptMenu> childList = new ArrayList<DeptMenu>();
        for (DeptMenu nav : allMenu) {
            // 遍历所有节点，将所有菜单的父id与传过来的根节点的id比较
            //相等说明：为该根节点的子节点。
            if (nav.getPid() == id) {
                childList.add(nav);
            }
        }
        //递归
        for (DeptMenu nav : childList) {
            nav.setChildren(getChild(nav.getId(), allMenu));
        }
        //如果节点下没有子节点，返回一个空List（递归退出）
        if (childList.size() == 0) {
            return new ArrayList<DeptMenu>();
        }
        return childList;
    }

    /**
     * 根据编号获取部门
     *
     * @Description: TODO(这里用一句话描述这个方法的作用)
     * @author zhlu
     * @date 2018年9月21日
     */
    @Override
    public Map<String, Object> getDetpMap(Map<String, Object> params) {
        Integer deptId = MapUtils.getInteger(params, "deptId");
        Map<String, Object> data = sysDeptDao.getDetpMap(params);
        //获取 绑定的公司列表数据
        List<Integer> areaIds = areaDeptService.selectAreaIdsByDeptId(deptId);
        data.put("areaIds", areaIds);

        if (params.get("deptId").toString().equals("0")) {
            data.put("parentName", "最高级部门");
        }
        return data;
    }

    /**
     * 插入一条新数据
     *
     * @param deptEntity
     * @return
     */
    @Override
    public boolean createDept(SysDeptEntity deptEntity) {
        //插入到主表
        boolean state = this.insert(deptEntity);
        if (state == false) {
            return false;
        }
        List<Integer> areaIds = deptEntity.getAreaList();
        //插入关联表
        List<SysAreaDeptEntity> insertData = Lists.newArrayList();
        for (int i = 0; i < areaIds.size(); i++) {
            SysAreaDeptEntity entity = new SysAreaDeptEntity();
            entity.setAreaId(areaIds.get(i));
            entity.setDeptId(deptEntity.getDeptId());
            entity.setInstm(new Date());
            insertData.add(entity);
        }
        boolean batch = areaDeptService.insertBatch(insertData);
        if (batch == false) {
            throw new RRException("插入失败");
        }
        return true;
    }

    /**
     * 修改 部门数据
     *
     * @param dept
     * @return
     */
    @Override
    public boolean updateDept(SysDeptEntity dept) {
        boolean state = this.updateById(dept);
        if (state == false) {
            return false;
        }
        List<Integer> areaIds = dept.getAreaList();
        //插入关联表
        List<SysAreaDeptEntity> insertData = Lists.newArrayList();
        for (int i = 0; i < areaIds.size(); i++) {
            SysAreaDeptEntity entity = new SysAreaDeptEntity();
            entity.setAreaId(areaIds.get(i));
            entity.setDeptId(dept.getDeptId());
            entity.setInstm(new Date());
            insertData.add(entity);
        }

        state = areaDeptService.deleteByMap(CustomMap.create("dept_id", dept.getDeptId()));
        if (state == false) {
            throw new RRException("更新失败");
        }

        boolean batch = areaDeptService.insertBatch(insertData);
        if (batch == false) {
            throw new RRException("修改失败");
        }
        return true;
    }

    @Override
    public JsonResult deleteDeptById(List<Integer> ids) {
        List<SysRoleDeptEntity> deleteData = Lists.newArrayList();
        for (Integer id : ids) {
            //判断是否有子部门
            List<Integer> deptList = this.queryDetpIdList(id);
            if (deptList.size() > 0) {
                return JsonResult.error("请先删除子部门");
            }
            //检测是否有绑定角色
            EntityWrapper wrapper = new EntityWrapper();
            wrapper.eq("dept_id", id);
            int count = roleDeptService.selectCount(wrapper);
            if (count != 0) {
                return JsonResult.error("请先解除绑定角色");
            }
        }


        boolean state = this.deleteBatchIds(ids);
        if (state == false) {
            return JsonResult.actionFailure();
        }

        //删除 角色中间表数据
        //删除 归属区域 中间表
        for (int i = 0; i < deleteData.size(); i++) {
            EntityWrapper wrapper = new EntityWrapper();
            wrapper.eq("dept_id", deleteData.get(i).getDeptId());
            boolean delete = roleDeptService.delete(wrapper);
            if (delete == false) {
                throw new RRException("删除失败 -1");
            }

            boolean deleteArea = areaDeptService.delete(wrapper);
            if (deleteArea == false) {
                throw new RRException("删除失败 -2");
            }
        }
        return JsonResult.actionSuccess();
    }


    @Override
    public List<SysDeptEntity> getChildDeptByParentId(Integer id) {
        return baseMapper.getChildDeptByParentId(id);
    }


    @Override
    public SysDeptEntity getDeptParentByDeptId(Integer id){
        return baseMapper.getParentDeptById(id);
    }

    /**
     * 功能描述: 
     * 获取所有的服务中心
     * @Author zhlu
     * @Description //TODO
     * @Date 2019/5/9 17:56
     */
    public List<Map<String,Object>>getServiceDeptList(){
        return sysDeptDao.getServiceDeptList();
    }

}
